using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections.ObjectModel;

namespace LibGreen.Jabber.ProtocolElements
{
    /// <summary>
    /// Describes the &lt;stream:features&gt; element
    /// </summary>
    public class FeaturesElement
    {
        private Element tlsElement;
        private Element authElement;
        private Element registerElement;
        private Element bindingElement;
        private Element sessionElement;
        private List<string> saslMechanisms = new List<string>();

        /// <summary>
        /// Initializes a FeaturesElement from a received <see cref="Element"/>
        /// </summary>
        /// <param name="element">The received <see cref="Element"/> containing the &lt;stream:features&gt; stanza</param>
        public FeaturesElement(Element element)
        {
            foreach (Element child in element.Children)
            {
                switch (child.Name.ToLowerInvariant())
                {
                    case "starttls":
                        tlsElement = child;
                        break;
                    case "auth":
                        authElement = child;
                        break;
                    case "register":
                        registerElement = child;
                        break;
                    case "bind":
                        bindingElement = child;
                        break;
                    case "session":
                        sessionElement = child;
                        break;
                    case "mechanisms":
                        foreach (Element mechanism in child.Children)
                        {
                            saslMechanisms.Add(mechanism.Value);
                        }
                        break;
                }
            }
        }

        /// <summary>
        /// Gets a value indicating whether resource binding is advertised by the server as being supported
        /// </summary>
        public bool IsBindingSupported
        {
            get { return bindingElement != null; }
        }

        /// <summary>
        /// Gets a value indicating whether resource binding is advertised by the server as required
        /// </summary>
        public bool IsBindingRequired
        {
            get
            {
                bool retval = false;
                if (bindingElement != null)
                {
                    retval = (bindingElement.Children.Count > 0 &&
                        bindingElement.Children[0].Name == "required");
                }
                return retval;
            }
        }

        /// <summary>
        /// Gets a value indicating whether session establishment is advertised by the server as required
        /// </summary>
        public bool IsSessionRequired
        {
            get { return sessionElement != null; }
        }

        /// <summary>
        /// Gets a list of the server-supported SASL mechanisms
        /// </summary>
        public ReadOnlyCollection<string> SupportedSASLMechanisms
        {
            get { return new ReadOnlyCollection<string>(saslMechanisms); }
        }
    }
}
